package com.example.library_base.http

import android.app.Application
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
import okhttp3.*
import okhttp3.HttpUrl.Companion.toHttpUrl
import okhttp3.logging.HttpLoggingInterceptor
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import java.security.SecureRandom
import java.security.cert.X509Certificate
import java.util.*
import java.util.concurrent.TimeUnit
import javax.inject.Singleton
import javax.net.ssl.SSLContext
import javax.net.ssl.SSLSocketFactory
import javax.net.ssl.X509TrustManager

@Module
@InstallIn(SingletonComponent::class)
object HttpModule {

    private const val DOMAIN_NAME: String = "Domain-Name"

    @Provides
    @Singleton
    fun provideRetrofit(okHttpClient: OkHttpClient): Retrofit =
            Retrofit.Builder()
                .baseUrl("https://www.baidu.com")
                .client(okHttpClient)
                .addConverterFactory(GsonConverterFactory.create())
                .build()

    @Provides
    fun provideOkHttpClient(application: Application) = OkHttpClient.Builder()
            .connectTimeout(60, TimeUnit.SECONDS)
            .readTimeout(60, TimeUnit.SECONDS)
            .addInterceptor(object : Interceptor{
                override fun intercept(chain: Interceptor.Chain): Response {
                    //配置请求头
                    val request = chain.request()
                    //从request获取原有的url
                    val oldHttpUrl = request.url
                    //获取request的创建者builder
                    val builder = request.newBuilder()

                    builder.header("User-Agent", "Android")
                        .addHeader("Content-Type", "application/json; charset=UTF-8")
                        .addHeader("Connection", "keep-alive")
                        .addHeader("Accept", "*/*")

                    //从request获取headers
                    val headerValues = request.headers(DOMAIN_NAME)
                    if (headerValues.isNotEmpty()){
                        builder.removeHeader(DOMAIN_NAME)
                        //匹配获得新url
                        val headerValue = headerValues[0]
                        val newBaseUrl: HttpUrl = headerValue.toHttpUrl()
                        //重新建立新的HttpUrl，修改需要修改的url部分
                        val newFullUrl = oldHttpUrl.newBuilder()
                            .scheme("https") //更换网络协议
                            .host(newBaseUrl.host) //更换主机名
                            .port(newBaseUrl.port) //更换端口
                            .build()

                        return chain.proceed(builder.url(newFullUrl).build())
                    }

                    return chain.proceed(builder.build())
                }
            })
            .addNetworkInterceptor(HttpLoggingInterceptor().apply {
                level = HttpLoggingInterceptor.Level.BODY
            })
            .retryOnConnectionFailure(true)
            .protocols(Collections.singletonList(Protocol.HTTP_1_1))
            .sslSocketFactory(getSSLSocketFactory(), getTrustManager()[0])
            .build()

    //获取这个SSLSocketFactory
    private fun getSSLSocketFactory(): SSLSocketFactory {
        return try {
            val sslContext = SSLContext.getInstance("SSL")
            sslContext.init(null, getTrustManager(), SecureRandom())
            sslContext.socketFactory
        } catch (e: Exception) {
            throw RuntimeException(e)
        }
    }

    //获取TrustManager
    private fun getTrustManager(): Array<X509TrustManager> {
        return arrayOf(
                object : X509TrustManager {
                    override fun checkClientTrusted(
                            chain: Array<X509Certificate?>?,
                            authType: String?
                    ) {
                    }

                    override fun checkServerTrusted(
                            chain: Array<X509Certificate?>?,
                            authType: String?
                    ) {

                    }

                    override fun getAcceptedIssuers(): Array<X509Certificate?> {
                        return arrayOf()
                    }
                }
        )
    }
}